package umg.gui;

import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.*;

import javax.swing.AbstractAction;
import javax.swing.JPopupMenu;
import javax.swing.MenuSelectionManager;
import javax.swing.SwingUtilities;
import javax.swing.text.*;

//from http://www.javalobby.org/java/forums/t19867.html
public class MyEventQueue extends EventQueue
{
	//TODO: This is the most time consuming method. 10-17-2009
	protected void dispatchEvent(AWTEvent event)
	{
		try
		{
			super.dispatchEvent(event);
		}
		catch (Exception e)
		{
			//e.printStackTrace();
			/*This is the exception:
			 * java.lang.ArrayIndexOutOfBoundsException: 4 >= 2
					at java.util.Vector.elementAt(Unknown Source)
					at javax.swing.table.DefaultTableColumnModel.getColumn(Unknown Source)
			 */
			System.out.println("Exception: " + e.getMessage() + " occurred trying to process event:" + event);
		}

		// interested only in mouseevents
		if (!(event instanceof MouseEvent)) return;

		MouseEvent me = (MouseEvent) event;

		// interested only in popuptriggers
		if (!me.isPopupTrigger()) return;

		// me.getComponent(...) retunrs the heavy weight component on which
		// event occured
		try
		{
			Component comp = SwingUtilities.getDeepestComponentAt(me.getComponent(), me.getX(), me.getY());

			// interested only in textcomponents
			if (!(comp instanceof JTextComponent)) return;

			// no popup shown by user code
			if (MenuSelectionManager.defaultManager().getSelectedPath().length > 0) return;

			// create popup menu and show
			JTextComponent tc = (JTextComponent) comp;
			JPopupMenu menu = new JPopupMenu();
			menu.add(new CutAction(tc));
			menu.add(new CopyAction(tc));
			menu.add(new PasteAction(tc));
			menu.add(new DeleteAction(tc));
			menu.addSeparator();
			menu.add(new SelectAllAction(tc));

			String text = ((JTextComponent) comp).getText();

			if (text != null && text.startsWith("<html>"))
			{
				menu.add(new CopyHTMLToClipboardAction(tc));
			}
			// make sure its an ip address
			if (text != null && text.matches("^[\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}$"))
			{
				// we have an IP address
				menu.addSeparator();
				menu.add(new KickAction(tc, text));
				menu.add(new BanAction(tc, text));
			}
			Point pt = SwingUtilities.convertPoint(me.getComponent(), me.getPoint(), tc);
			menu.show(tc, pt.x, pt.y);
		}
		catch (NullPointerException npe)
		{
			// System.out.println(npe.getMessage());
		}
	}// dispatchEvent
}

class CopyHTMLToClipboardAction extends AbstractAction
{
	/**
	 *
	 */
	private static final long serialVersionUID = 5943934608347252668L;
	JTextComponent comp;

	public CopyHTMLToClipboardAction(JTextComponent comp)
	{
		super("Copy chat HTML");
		this.comp = comp;
	}

	public void actionPerformed(ActionEvent e)
	{
		Toolkit tk = Toolkit.getDefaultToolkit();
		StringSelection st = new StringSelection(comp.getText().replaceAll("<body>", "<body bgcolor=\"#243954\">"));
		Clipboard cp = tk.getSystemClipboard();
		cp.setContents(st, st);
	}

	public boolean isEnabled()
	{
		return comp.getText().length() > 0;
	}
}

class KickAction extends AbstractAction
{
	// GUI gui;
	String ip;
	private static final long serialVersionUID = 6056353603667095636L;
	JTextComponent comp;

	public KickAction(JTextComponent comp, String ip)
	{
		super("Kick " + ip);
		this.comp = comp;
		// this.gui=gui;
		this.ip = ip;
	}

	public void actionPerformed(ActionEvent e)
	{
		GUI.kickIP(ip);
	}

	public boolean isEnabled()
	{
		return true;
	}
}

class BanAction extends AbstractAction
{
	// GUI gui;
	String ip;

	private static final long serialVersionUID = 6056353603667095636L;
	JTextComponent comp;

	public BanAction(JTextComponent comp, String ip)
	{
		super("Ban " + ip);
		this.comp = comp;
		// this.gui=gui;
		this.ip = ip;
	}

	public void actionPerformed(ActionEvent e)
	{
		GUI.banIP(ip);
	}

	public boolean isEnabled()
	{
		return true;
	}
}

class CutAction extends AbstractAction
{
	/**
	 *
	 */
	private static final long serialVersionUID = 6056353603667095636L;
	JTextComponent comp;

	public CutAction(JTextComponent comp)
	{
		super("Cut");
		this.comp = comp;
	}

	public void actionPerformed(ActionEvent e)
	{
		comp.cut();
	}

	public boolean isEnabled()
	{
		return comp.isEditable() && comp.isEnabled() && comp.getSelectedText() != null;
	}
}

class PasteAction extends AbstractAction
{
	/**
	 *
	 */
	private static final long serialVersionUID = 800493879564612752L;
	JTextComponent comp;

	public PasteAction(JTextComponent comp)
	{
		super("Paste");
		this.comp = comp;
	}

	public void actionPerformed(ActionEvent e)
	{
		comp.paste();
	}

	public boolean isEnabled()
	{
		if (comp.isEditable() && comp.isEnabled())
		{
			Transferable contents = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this);
			return contents.isDataFlavorSupported(DataFlavor.stringFlavor);
		}
		else return false;
	}
}

class DeleteAction extends AbstractAction
{
	/**
	 *
	 */
	private static final long serialVersionUID = 1955809195625118274L;
	JTextComponent comp;

	public DeleteAction(JTextComponent comp)
	{
		super("Delete");
		this.comp = comp;
	}

	public void actionPerformed(ActionEvent e)
	{
		comp.replaceSelection(null);
	}

	public boolean isEnabled()
	{
		return comp.isEditable() && comp.isEnabled() && comp.getSelectedText() != null;
	}
}

class CopyAction extends AbstractAction
{
	/**
	 *
	 */
	private static final long serialVersionUID = 5943934608347252666L;
	JTextComponent comp;

	public CopyAction(JTextComponent comp)
	{
		super("Copy");
		this.comp = comp;
	}

	public void actionPerformed(ActionEvent e)
	{
		comp.copy();
	}

	public boolean isEnabled()
	{
		return comp.isEnabled() && comp.getSelectedText() != null;
	}
}

class SelectAllAction extends AbstractAction
{
	private static final long serialVersionUID = -1357193988171478013L;
	JTextComponent comp;

	public SelectAllAction(JTextComponent comp)
	{
		super("Select All");
		this.comp = comp;
	}

	public void actionPerformed(ActionEvent e)
	{
		comp.selectAll();
	}

	public boolean isEnabled()
	{
		return comp.isEnabled() && comp.getText().length() > 0;
	}
}
